package com.imooc.course.server.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.imooc.course.server.dao.UserDao;
import com.imooc.course.server.dto.LoginUserDto;
import com.imooc.course.server.dto.ResourceDto;
import com.imooc.course.server.dto.UserDto;
import com.imooc.course.server.dto.PageDto;
import com.imooc.course.server.entity.User;
import com.imooc.course.server.entity.UserExample;
import com.imooc.course.server.enums.BusinessExceptionEnum;
import com.imooc.course.server.exception.BusinessException;
import com.imooc.course.server.service.ResourceService;
import com.imooc.course.server.service.UserService;
import com.imooc.course.server.utils.CopyUtil;
import com.imooc.course.server.utils.UuidUtil;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service("userService")
public class UserServiceImpl implements UserService {

    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    @Resource(name = "userDao")
    private UserDao userDao;

    @Resource(name = "resourceService")
    private ResourceService resourceService;

    @Resource(name = "data_Source")
    private ComboPooledDataSource datasource;
    /**
     * 列表查询
     * @param pageDto
     */
    @Override
    public void getList(PageDto pageDto) {
        PageHelper.startPage(pageDto.getPage(),pageDto.getSize());

        UserExample userExample = new UserExample();
        List<User> userList = userDao.selectByExample(userExample);

        PageInfo<User> userPageInfo = new PageInfo<>(userList);
        pageDto.setTotal(userPageInfo.getTotal());

        List<UserDto> userDtoList = CopyUtil.copyList(userList, UserDto.class);

        pageDto.setList(userDtoList);
    }

    /**
     * 保存，id有值为更新，id无值为新增
     * @param userDto
     */
    @Override
    public void save(UserDto userDto) {
        User user = CopyUtil.copy(userDto, User.class);
        String id = userDto.getId() != null ? userDto.getId().trim() : userDto.getId();
        if (StringUtils.isEmpty(id)) {
            this.addUser(user);
        }else{
            this.updateUser(user);
        }
    }

    private void updateUser(User user) {
        //因已专门设置更新密码的业务功能，所以这里不需要更新密码。
        user.setPassword(null);
        userDao.updateByPrimaryKeySelective(user);
    }

    private void addUser(User user) {
        user.setId(UuidUtil.getShortUuid());
        User userDb = this.findByLoginName(CopyUtil.copy(user,UserDto.class));
        if (userDb != null) {
            throw new BusinessException(BusinessExceptionEnum.USER_LOGIN_NAME_EXIST);
        } else {
            userDao.insertSelective(user);
        }
    }

    @Override
    public User findByLoginName(UserDto userDto) {
        UserExample userExample = new UserExample();
        userExample.createCriteria().andLoginNameEqualTo(userDto.getLoginName());
        List<User> userList = userDao.selectByExample(userExample);
        return userList.size() != 0 ? userList.get(0) : null;
    }

    /**
     * 重置密码
     * @param userDto
     */
    @Override
    public void savePassword(UserDto userDto) {
        User user = new User();
        user.setId(userDto.getId());
        user.setPassword(userDto.getPassword());
        userDao.updateByPrimaryKeySelective(user);
    }

    /**
     * 删除
     * @param id
     */
    @Override
    public void delete(String id) {
        userDao.deleteByPrimaryKey(id);
    }

    /**
     * 用户登录
     * @param userDto
     * @return
     */
    @Override
    public LoginUserDto login(UserDto userDto) {
        //验证登录信息是否和数据信息一致
        User user = this.findByLoginName(userDto);
        if (user == null) {
            log.info("登录名不存在 = {}", userDto.getLoginName());
            throw new BusinessException(BusinessExceptionEnum.LOGIN_ERROR);
        } else {
            if (userDto.getPassword().equals(user.getPassword())) {
                log.info("云数据库 = {}", datasource.getJdbcUrl());
                //登录成功
                LoginUserDto loginUserDto = CopyUtil.copy(user, LoginUserDto.class);
                //读取登录用户的权限并设置
                this.setAuth(loginUserDto);
                return loginUserDto;
            } else {
                //登录失败
                log.info("登录密码 = {}, 数据库密码 = {}",userDto.getPassword(),user.getPassword());
                throw new BusinessException(BusinessExceptionEnum.LOGIN_ERROR);
            }
        }
    }

    private void setAuth(LoginUserDto loginUserDto) {
        List<ResourceDto> resourceDtoList = resourceService.readUserAuth(loginUserDto);
        loginUserDto.setResources(resourceDtoList);

        Set<String> requestSet = new HashSet<>();
        resourceDtoList.stream()
                .forEach(r -> {
                    List<String> list = JSON.parseArray(r.getRequest(), String.class);
                    if (!CollectionUtils.isEmpty(list)) {
                        requestSet.addAll(list);
                    }
                });
        log.info("拥有的权限：{}", requestSet);
        loginUserDto.setRequests(requestSet);
    }


    /**
     * 获取所有用户
     * @return
     */
    @Override
    public List<UserDto> getListAll() {
        List<User> users = userDao.selectByExample(new UserExample());
        return CopyUtil.copyList(users,UserDto.class);
    }
}
